package org.aspire.data;

/******************************************************************************
 * A utility class for manipulating primitive data and their object 
 * counterpart including strings.
 * 
 * @author JPACarabuena
 *****************************************************************************/
public final class Data {

	// ========================================================================
	// Constants
	// ========================================================================

	public static final int INVALID = Integer.MIN_VALUE;
	
	public static final int INTEGER = 1;
	public static final int LONG	= 2;
	public static final int FLOAT	= 3;
	public static final int DOUBLE	= 4;
	public static final int STRING	= 5;
	public static final int CHAR	= 6;
	public static final int BYTE	= 7;
	public static final int BOOLEAN	= 8;
	
	// ========================================================================
	// Static Methods
	// ========================================================================

	/**************************************************************************
	 * @param o1
	 * @param o2
	 * @param type
	 * @return
	 *************************************************************************/
	public static int compare(Object o1, Object o2, int type) {
		if(type == Data.INTEGER) {
			return Data.compareInt(o1, o2);
		} else if(type == Data.LONG) {
			return Data.compareLong(o1, o2);
		} else if(type == Data.FLOAT) {
			return Data.compareFloat(o1, o2);
		} else if(type == Data.DOUBLE) {
			return Data.compareDouble(o1, o2);
		} else if(type == Data.STRING) {
			return Data.compareString(o1, o2);
		} else if(type == Data.CHAR) {
			return Data.compareChar(o1, o2);
		} else {
			return Data.INVALID;
		}
	}
	
	/**************************************************************************
	 * Compares the two specified object. If the objects are not integers, then
	 * the invalid flag will be returned instead.
	 * <p>
	 * The comparison result is relative to the first object specified.
	 * 
	 * @param o1	the first object.
	 * @param o2	the second object.
	 * @return	whether the first object is equal to, less than or greater than
	 * 			the second object, or the comparison is invalid.
	 *************************************************************************/
	private static int compareInt(Object o1, Object o2) {
		Integer x1, x2;
		
		// Try to cast the two objects
		try {
			x1 = (Integer) o1;
			x2 = (Integer) o2;
		} catch(ClassCastException e) {
			return Data.INVALID;
		}
		
		return x1.compareTo(x2);
	}

	/**************************************************************************
	 * Compares the two specified object. If the objects are not long values,
	 * then the invalid flag will be returned instead.
	 * <p>
	 * The comparison result is relative to the first object specified.
	 * 
	 * @param o1	the first object.
	 * @param o2	the second object.
	 * @return	whether the first object is equal to, less than or greater than
	 * 			the second object, or the comparison is invalid.
	 *************************************************************************/
	private static int compareLong(Object o1, Object o2) {
		Long x1, x2;
		
		// Try to cast the two objects
		try {
			x1 = (Long) o1;
			x2 = (Long) o2;
		} catch(ClassCastException e) {
			return Data.INVALID;
		}
		
		return x1.compareTo(x2);
	}

	/**************************************************************************
	 * Compares the two specified object. If the objects are not floating point
	 * values, then the invalid flag will be returned instead.
	 * <p>
	 * The comparison result is relative to the first object specified.
	 * 
	 * @param o1	the first object.
	 * @param o2	the second object.
	 * @return	whether the first object is equal to, less than or greater than
	 * 			the second object, or the comparison is invalid.
	 *************************************************************************/
	private static int compareFloat(Object o1, Object o2) {
		Float x1, x2;
		
		// Try to cast the two objects
		try {
			x1 = (Float) o1;
			x2 = (Float) o2;
		} catch(ClassCastException e) {
			return Data.INVALID;
		}
		
		return x1.compareTo(x2);
	}

	/**************************************************************************
	 * Compares the two specified object. If the objects are not double values, 
	 * then the invalid flag will be returned instead.
	 * <p>
	 * The comparison result is relative to the first object specified.
	 * 
	 * @param o1	the first object.
	 * @param o2	the second object.
	 * @return	whether the first object is equal to, less than or greater than
	 * 			the second object, or the comparison is invalid.
	 *************************************************************************/
	private static int compareDouble(Object o1, Object o2) {
		Double x1, x2;
		
		// Try to cast the two objects
		try {
			x1 = (Double) o1;
			x2 = (Double) o2;
		} catch(ClassCastException e) {
			return Data.INVALID;
		}
		
		return x1.compareTo(x2);
	}

	/**************************************************************************
	 * Compares the two specified object. If the objects are not strings, then
	 * the invalid flag will be returned instead.
	 * <p>
	 * The comparison result is relative to the first object specified.
	 * 
	 * @param o1	the first object.
	 * @param o2	the second object.
	 * @return	whether the first object is equal to, less than or greater than
	 * 			the second object, or the comparison is invalid.
	 *************************************************************************/
	private static int compareString(Object o1, Object o2) {
		String x1, x2;
		
		// Try to cast the two objects
		try {
			x1 = (String) o1;
			x2 = (String) o2;
		} catch(ClassCastException e) {
			return Data.INVALID;
		}
		
		return x1.compareTo(x2);
	}

	/**************************************************************************
	 * Compares the two specified object. If the objects are not characters,
	 * then the invalid flag will be returned instead.
	 * <p>
	 * The comparison result is relative to the first object specified.
	 * 
	 * @param o1	the first object.
	 * @param o2	the second object.
	 * @return	whether the first object is equal to, less than or greater than
	 * 			the second object, or the comparison is invalid.
	 *************************************************************************/
	private static int compareChar(Object o1, Object o2) {
		Character x1, x2;
		
		// Try to cast the two objects
		try {
			x1 = (Character) o1;
			x2 = (Character) o2;
		} catch(ClassCastException e) {
			return Data.INVALID;
		}
		
		return x1.compareTo(x2);
	}
	
	// ========================================================================
	// Fields
	// ========================================================================

	// ========================================================================
	// Constructors
	// ========================================================================

	/**************************************************************************
	 * Hidden constructor to avoid instantiation of this class.
	 *************************************************************************/
	protected Data() {
		
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================

	// ========================================================================
	// Override Methods
	// ========================================================================

	// ========================================================================
	// Methods
	// ========================================================================

	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}
